using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Remoting;

namespace PS.Framework.Remoting
{
	public class RemotingServer<T> where T: new()
	{
		#region Fields

		#endregion

		#region Properties

		private string _sConfigFile;
		/// <summary>
		/// gets or sets the config file
		/// </summary>
		public string ConfigFile
		{
			get { return _sConfigFile; }
			set { _sConfigFile = value; }
		}

		private bool _bIsOpen;
		/// <summary>
		/// gets or sets if server is open
		/// </summary>
		public bool IsOpen
		{
			get { return _bIsOpen; }
		}

		private RemotingInterface<T> _interface = new RemotingInterface<T>();
		/// <summary>
		/// gets or sets the logger interface
		/// </summary>
		public RemotingInterface<T> Interface
		{
			get { return _interface; }
			set {

				if (this._interface != value)
				{
					if (this._bIsOpen)
						throw new InvalidOperationException("The Interface instance could not be when the server connection is open");

					if (value != null)
						if (value as MarshalByRefObject == null)
							throw new ArgumentException("The Interface instance must be inherited from MarshalByRefObject");

					this._interface = value;
				}				
				_interface = value;
			}
		}
	
		#endregion

		#region Construction / Destruction

		#endregion

		#region Methods

		/// <summary>
		/// Open the server connection
		/// </summary>
		public void Open()
		{
			// check if the interface is null because then we can't
			// provide it for remote access
			if (this._interface == null)
				throw new InvalidOperationException("There is no Interface instance that could be marshalled");

			// configure the remotingchannel etc.
			RemotingConfiguration.Configure(this._sConfigFile, false);
             
			this._bIsOpen = true; 

		}

		/// <summary>
		/// close the server connection
		/// </summary>
		public void Close()
		{
			if (this._bIsOpen)
			{
				// disconnect the provided object
				// so no more remote access will be 
                this._interface.RemotingObject = default(T);
                this._interface = null;
			}
		}

		#endregion

        //public static void RaiseEvent(string eventName, EventArgs e)
        //{
        //    INotificationService notificationServiceProxy = NotificationService.Instance;
        //    notificationServiceProxy.RaiseEvent(eventName, e);
        //}

        //public static EventHandler SubscribeEvent(string eventName, EventHandler handler)
        //{
        //    EventWrapper wrapper = new EventWrapper(handler);
        //    INotificationService notificationServiceProxy = NotificationService.Instance;
        //    notificationServiceProxy.Subscribe(eventName, wrapper.WrapperServerEventHandler);

        //    return wrapper.WrapperServerEventHandler;
        //}
	}
}
